package com.qilu.careprogram.dao;

import com.qilu.careprogram.pojo.entity.PatientInfo;
import com.qilu.careprogram.pojo.entity.PatientInit;
import com.qilu.careprogram.pojo.dto.UpdateHotArticleDTO;
import com.qilu.careprogram.pojo.entity.Carousel;
import com.qilu.careprogram.pojo.entity.HotArticle;
import com.qilu.careprogram.pojo.dto.PatientLoginDTO;
import com.qilu.careprogram.pojo.entity.Drug;
import com.qilu.careprogram.pojo.entity.UserLike;
import com.qilu.careprogram.pojo.dto.UnregisteredPatientDTO;
import com.qilu.careprogram.pojo.vo.CycleRemindVO;
import com.qilu.careprogram.pojo.vo.PatientInfoVO;
import com.qilu.careprogram.pojo.vo.ReviewInfoVO;
import com.qilu.careprogram.pojo.vo.ProstateCancerVO;
import com.qilu.careprogram.pojo.vo.ReturnVisitVO;
import org.apache.ibatis.annotations.*;

import java.util.Date;
import java.util.List;

@Mapper
public interface PatientInfoDAO {

    /**
     * 根据医院编号查询收藏的文章ID
     */
    List<Long> selectHotArticleIdsByHospitalNumber(@Param("hospitalNumber") String hospitalNumber);

    /**
     * 根据医院编号和文章ID删除收藏
     */
    int deleteByHospitalNumberAndArticleId(
            @Param("hospitalNumber") String hospitalNumber,
            @Param("hotArticleId") Long hotArticleId
    );

    /**
     * 插入收藏记录
     */
    void insertUserLike(UserLike userLike);

    /**
     * 根据ID查询热门文章（检查文章是否存在）
     */
    HotArticle selectHotArticleById(@Param("id") Long id);

    /**
     * 查询用户收藏的文章详情
     */
    List<HotArticle> selectHotArticlesByUserLikes(@Param("hospitalNumber") String hospitalNumber);

    /**
     * 获取所有轮播图
     */
    List<Carousel> getAllCarousel();

    /**
     * 获取所有热门文章
     */
    List<HotArticle> getAllHotArticles();

    /**
     * 添加轮播图
     */
    @Insert("INSERT INTO carousel (picture, authority, isused) VALUES (#{picture}, #{authority}, #{isused})")
    void addCarousel(Carousel carousel);

    /**
     * 添加热门文章
     */
    @Insert("INSERT INTO hot_articles (name, description, picture, pcurl, authority, isused) " +
            "VALUES (#{name}, #{description}, #{picture}, #{pcurl}, #{authority}, #{isused})")
    void addHotArticle(HotArticle article);

    /**
     * 更新轮播图状态
     */
    @Update("UPDATE carousel SET isused = #{isused} WHERE id = #{id}")
    void updateCarouselIsused(@Param("id") Long id, @Param("isused") String isused);

    /**
     * 更新热门文章状态
     */
    @Update("UPDATE hot_articles SET isused = #{isused} WHERE id = #{id}")
    void updateHotArticleIsused(@Param("id") Long id, @Param("isused") String isused);

    /**
     * 更新轮播图信息
     */
    @Update("UPDATE carousel SET picture = #{picture} WHERE id = #{id}")
    void updateCarousel(@Param("id") Long id, @Param("picture") String picture);

    /**
     * 更新热门文章信息
     */
    @Update("UPDATE hot_articles SET name = #{name}, description = #{description}, " +
            "picture = #{picture}, pcurl = #{pcurl} WHERE id = #{id}")
    void updateHotArticle(UpdateHotArticleDTO dto);

    /**
     * 查询所有药品信息
     * @return 药品列表
     */
    List<Drug> getAllDrug();

    /**
     * 修改药品启用状态
     * @param id 药品ID
     * @param isused 新状态（启用/禁用）
     * @return 影响行数
     */
    int updateDrugUse(@Param("id") Long id, @Param("isused") String isused);

    /**
     * 添加药品
     * @param drug 药品信息
     * @return 影响行数（自动生成的ID会回写到drug对象）
     */
    int addDrug(Drug drug);

    /**
     * 修改药品信息
     * @param drug 药品信息（含ID）
     * @return 影响行数
     */
    int updateDrug(Drug drug);

    /**
     * 查询复查信息
     * @param hospitalNumber 住院号
     * @param reviewItem 复查项目
     * @param startTime 预约开始时间
     * @param endTime 预约结束时间
     * @return 复查信息列表
     */
    List<ReviewInfoVO> getReviewInfo(
            @Param("hospitalNumber") String hospitalNumber,
            @Param("reviewItem") String reviewItem,
            @Param("startTime") String startTime,
            @Param("endTime") String endTime);

    String getIdCardByHospitalNumber(@Param("hospitalNumber") String hospitalNumber);

    List<UnregisteredPatientDTO> getUnregisteredPatients(@Param("disease") String disease);

    /**
     * 根据住院号获取科室
     * @param hospitalNumber 住院号
     * @return 科室
     */
    String getAuthorityByHospitalNumber(@Param("hospitalNumber") String hospitalNumber);

    /**
     * 根据手机号查找患者登录信息
     * @param IDNumber 身份证号
     * @return 患者登录信息 DTO
     */
    PatientLoginDTO getPatientByIdNumber(String IDNumber);

    /**
     * 根据住院号获取身份证号
     * @param hospitalNumber 住院号
     * @return 身份证号
     */
    String getIdcByHospitalNumber(@Param("hospitalNumber") String hospitalNumber);

    /**
     * 重置患者账号、密码
     * @param patientLoginDTO 新的账号密码信息
     */
    void updatePatientPassword(PatientLoginDTO patientLoginDTO);

    /**
     * 根据住院号查找患者登录信息
     * @param hospitalNumber 住院号
     * @return 患者登录信息 DTO
     */
    PatientLoginDTO getPatientByHospitalNumber(@Param("hospitalNumber") String hospitalNumber);

    /**
     * 根据条件查询患者信息
     * @param gender 性别
     * @param startAge 起始年龄
     * @param endAge 结束年龄
     * @param disease 疾病类型
     * @return 查询结果
     */
    List<PatientInfoVO> selectPatientInfo(@Param("gender") String gender, @Param("startAge") int startAge, @Param("endAge") int endAge, @Param("disease") String disease);

    /**
     * 检索病人是否存在
     * @param hospitalNumber
     * @return 累计回访次数
     */
    Integer getPatientReVisitsNum(String hospitalNumber);

    /**
     * 插入新病人信息
     * @param patientInfo
     */
    void insert(PatientInfo patientInfo);

    void update(PatientInfo patientInfo);

    /**
     * 根据住院号获取病人信息
     * @param hospitalNumber
     * @return
     */
    PatientInfo getPatientInfoByHospitalNumber(String hospitalNumber);

    /**
     * 获取全部的病人的信息
     * @return
     */
    List<PatientInfo> getPatientInfo();

    /**
     * 按照时间范围获取病人信息
     * @param startTime
     * @param endTime
     * @return
     */
    List<PatientInfo> getPatientInfoByDate(@Param("startTime") Date startTime, @Param("endTime") Date endTime);

    List<PatientInfo> getProstateCancerPatientInfo(@Param("disease") String disease);

    /**
     * 根据住院号查询患者ID（优化查询）
     * @param hospitalNumber 住院号
     * @return 患者ID
     */
    Long getIdByHospitalNumber(@Param("hospitalNumber") String hospitalNumber);

    /**
     * 根据身份证号查询是否存在
     * @param idCard 身份证号
     * @return 存在返回ID，否则返回null
     */
    Long getIdByIdCard(@Param("idCard") String idCard);

    /**
     * 插入患者信息（仅住院号和科室）
     * @param patientInit 患者信息
     */
    void insertPatientInit(PatientInit patientInit);

    /**
     * 根据住院号删除患者
     * @param hospitalNumber 住院号
     * @return 删除结果
     */
    void deleteByHospitalNumber(String hospitalNumber);

    void deleteLoginByHospitalNumber(String hospitalNumber);

    void deleteMNZKHospitalNumber(String hospitalNumber);

    void deleteQLXAHospitalNumber(String hospitalNumber);

    void deletePatientInfoByHospitalNumber(String hospitalNumber);

    /**
     * 根据用户名查找患者
     * @param patientUserName 用户名
     * @return 患者登录信息 DTO
     */
    PatientLoginDTO getPatientByUsername(@Param("patientUserName") String patientUserName);

    /**
     * 确认信息填报
     * @param hospitalNumber 患者住院号
     * @return 患者填写信息 DTO
     */
    PatientInfo getPatientAllInfoByHospitalNumber(String hospitalNumber);

    /**
     * 插入患者登录信息
     * @param patientLoginDTO 患者登录信息 DTO
     */
    void insertPatientLogin(PatientLoginDTO patientLoginDTO);

    void updatePatientLoginPhone(@Param("hospitalNumber") String hospitalNumber,
                                 @Param("phone") String phone);

    PatientLoginDTO getPatientByHospitalNumberAndIdNumber(PatientLoginDTO patientLoginDTO);


    List<CycleRemindVO> getCycleRemindInfo(@Param("authority") String authority,
                                           @Param("hospitalNumber") String hospitalNumber,
                                           @Param("idCard") String idCard,
                                           @Param("cycleInterval") String cycleInterval,
                                           @Param("limitInterval") String limitInterval,
                                           @Param("ifBeyondInterval") String ifBeyondInterval);

    void changePatientInterval(@Param("hospitalNumber") String hospitalNumber, @Param("newInterval") String newInterval);

    List<CycleRemindVO> getPatientWithoutInfoForRemind(@Param("authority") String authority,
                                                       @Param("hospitalNumber") String hospitalNumber,
                                                       @Param("idCard") String idCard,
                                                       @Param("limitInterval") String limitInterval);

    String getHospitalNumberByIdCard(String idNumber);
}
